package com.yy.socket;

import java.util.HashMap;
import java.util.List;

import com.yy.model.ResultMsg;
import com.yy.utils.JwtUtils;
import com.yy.utils.SessionUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.tio.core.ChannelContext;
import org.tio.core.ChannelContextFilter;
import org.tio.core.Tio;
import org.tio.http.common.HttpRequest;
import org.tio.http.common.HttpResponse;
import org.tio.utils.json.Json;
import org.tio.utils.lock.SetWithLock;
import org.tio.websocket.common.WsRequest;
import org.tio.websocket.server.handler.IWsMsgHandler;
import com.alibaba.fastjson.JSON;
import com.yy.ant.chat.entity.Flock;
import com.yy.ant.chat.service.IFlockService;
import com.yy.ant.sys.entity.User;
import com.yy.ant.sys.service.IUserService;
import com.yy.model.ReceiveMessage;
import com.yy.model.SocketMsg;
import com.yy.socket.handler.DelFriendMessageHandler;
import com.yy.socket.handler.GroupMessageHandler;
import com.yy.socket.handler.JoinGroupMessageHandler;
import com.yy.socket.handler.LoginMessageHandler;
import com.yy.socket.handler.MsgHandlerInterface;
import com.yy.socket.handler.OldMessageHandler;
import com.yy.socket.handler.OutGroupMessageHandler;
import com.yy.socket.handler.P2PMessageHandler;
import com.yy.socket.handler.ReqMessageHandler;
import com.yy.utils.SocketMsgUtils;

@Component
public class MyWebSocketMsgHandler implements IWsMsgHandler {

	@Autowired
	private IFlockService iFlockService;

	@Autowired
	private IUserService iUserService;
	
	@Autowired
	private P2PMessageHandler p2pMessageHandler;
	
	@Autowired
	private GroupMessageHandler groupMessageHandler;
	
	@Value("${yy.touxiang}")
	private String url;
	
	private static Logger log = LoggerFactory.getLogger(MyWebSocketMsgHandler.class);
	
	@Override
	public HttpResponse handshake(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext)
			throws Exception {
		// 验证合法性
		String sessionId = httpRequest.getParam("sessionId");
		String id = httpRequest.getParam("id");
		User u= SessionUtil.getUserToSession(sessionId);
		if(!u.isSuccess()){
			log.debug("用户未登录!");
			return null;
		}
		if (StringUtils.isBlank(sessionId)) {
			log.debug("用户未登录!");
			return null;
		}
		User user = iUserService.getById(id);
		if (user == null) {
			log.debug("用户不存在!");
			return null;
		}
		// 绑定用户
		channelContext.setAttribute("userName", user.getUsername());
		channelContext.setAttribute("userid", user.getId());
		Tio.bindUser(channelContext, id);
		// 绑定群组
		bindGroup(Long.valueOf(id), channelContext);
		// 上线
		iUserService.online(Long.valueOf(id));
		// 上线通知
		onLineMsg(user, channelContext);
		return httpResponse;
	}

	@Override
	public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext)
			throws Exception {
		System.out.println("握手成功");
	}

	@Override
	public Object onBytes(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
		String s = new String(bytes, "utf-8");
		System.out.println("接收到文本消息：" + s);
		ReceiveMessage msgData = JSON.parseObject(s, ReceiveMessage.class);
		String action =msgData.getAction();
		if(!Strings.isBlank(action) && !"".equalsIgnoreCase(action)){
			switch (action) {
			case TypeToString.P2P_REQ:
				p2pMessageHandler.handler(s,channelContext);
				break;
			case TypeToString.GROUP_MSG_REQ:
				groupMessageHandler.handler(s,channelContext);
				break;
			}
		}else{
			log.debug("非法请求...");
		}
		return null;
	}

	@Override
	public Object onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
		// 下线
		String userid = String.valueOf(channelContext.getAttribute("userid"));
		if (!Strings.isBlank(userid)) {
			iUserService.hide(Long.valueOf(userid));
		}
		// 下线通知
		offLineMsg(String.valueOf(channelContext.getAttribute("userName")),String.valueOf(channelContext.getAttribute("userid")), channelContext);
		return null;
	}

	@Override
	public Object onText(WsRequest wsRequest, String s, ChannelContext channelContext) throws Exception {
		System.out.println("接收到文本消息：" + s);
		ReceiveMessage msgData = JSON.parseObject(s, ReceiveMessage.class);
		String action =msgData.getAction();
		if(!Strings.isBlank(action) && !"".equalsIgnoreCase(action)){
			switch (action) {
			case TypeToString.P2P_REQ:
				p2pMessageHandler.handler(s,channelContext);
				break;
			case TypeToString.GROUP_MSG_REQ:
				groupMessageHandler.handler(s,channelContext);
				break;
			}
		}else{
			log.debug("非法请求...");
		}
		return null;
	}

	/**
	 * 绑定群组
	 * 
	 * @param id
	 * @param context
	 */
	public void bindGroup(Long id, ChannelContext context) {
		List<Flock> list = iFlockService.getFlocks(id,url);
		if (list != null && list.size() > 0) {
			for (Flock f : list) {
				Tio.bindGroup(context, f.getId().toString());
			}
		}
	}

	/**
	 * 上线通知
	 */
	public void onLineMsg(User user, ChannelContext context) {
		// 直接调用 sendToAll方法会导致错误,不知何种原因
		HashMap<String, Object> hashMap = new HashMap<String, Object>();
		hashMap.put("msg", user.getUsername() + "上线了!");
		hashMap.put("id", user.getId().toString());
		try {
			Tio.sendToGroup(context.getTioConfig(), user.getId().toString(),
					SocketMsgUtils.madeWsResponse(Type.SUCCESS_MESSAGE_RESP, Json.toJson(hashMap)), new ChannelContextFilter() {
						@Override
						public boolean filter(ChannelContext channelContext) {
							if (channelContext == context) {
								return false;
							} else {
								return true;
							}
						}
					});
		}catch (Exception e){}
	}
	/**
	 * 下线通知
	 */
	public void offLineMsg(String name,String id,ChannelContext context){
		SetWithLock<ChannelContext> allConnectedsChannelContexts = Tio.getAll(context.getTioConfig());
		HashMap<String, Object> hashMap = new HashMap<String, Object>();
		User user = iUserService.getById(id);
		hashMap.put("msg", name + "下线了!");
		hashMap.put("id", user.getId().toString());
		try {
			Tio.sendToGroup(context.getTioConfig(), user.getId().toString(),
					SocketMsgUtils.madeWsResponse(Type.FAIL_MESSAGE_RESP, Json.toJson(hashMap)), new ChannelContextFilter() {
						@Override
						public boolean filter(ChannelContext channelContext) {
							if (channelContext == context) {
								return false;
							} else {
								return true;
							}
						}
					});
		}catch (Exception e){}

	}
}
